Ejercicio 0

Pruebas para entender qué tengo que hacer


In [5]:
class Matriz:
    def __init__(self):
        pass # this means do nothing in Python
    def __repr__(self):
        return "[[2,3,5] \n [7,11,13]]"
    def __str__(self):
        return "[[2,3,5] \n [7,11,13]]"

In [6]:
m=Matriz()

In [7]:
m


Out[7]:
[[2,3,5] 
 [7,11,13]]

In [8]:
print(m)


[[2,3,5] 
 [7,11,13]]

Ejercicio 1

Imprimir como matriz


In [495]:
class Array:
    "Una clase minima para algebra lineal"    
    def __init__(self, list_of_rows): 
        "Constructor y validador"
        # obtener dimensiones
        self.data = list_of_rows
        nrow = len(list_of_rows)
        #  ___caso vector: redimensionar correctamente
        if not isinstance(list_of_rows[0], list):
            nrow = 1
            self.data = [[x] for x in list_of_rows]
        # ahora las columnas deben estar bien aunque sea un vector
        ncol = len(self.data[0])
        self.shape = (nrow, ncol)
        # validar tamano correcto de filas
        if any([len(r) != ncol for r in self.data]):
            raise Exception("Las filas deben ser del mismo tamano")
            
    def __repr__(self):
        return "\n".join(str(x) for x in self.data)
    
    def __str__(self):
        return "\n".join(repr(x) for x in self.data)

In [496]:
A = Array([[2,3,5], [7,11,13]])

In [497]:
print(A)


[2, 3, 5]
[7, 11, 13]

In [499]:
A


Out[499]:
[2, 3, 5]
[7, 11, 13]

Ejercicio 2

Modificar/Leer elementos de un array


In [12]:
class Array:
    "Una clase minima para algebra lineal"    
    def __init__(self, list_of_rows): 
        "Constructor y validador"
        # obtener dimensiones
        self.data = list_of_rows
        nrow = len(list_of_rows)
        #  ___caso vector: redimensionar correctamente
        if not isinstance(list_of_rows[0], list):
            nrow = 1
            self.data = [[x] for x in list_of_rows]
        # ahora las columnas deben estar bien aunque sea un vector
        ncol = len(self.data[0])
        self.shape = (nrow, ncol)
        # validar tamano correcto de filas
        if any([len(r) != ncol for r in self.data]):
            raise Exception("Las filas deben ser del mismo tamano")
    
    def __getitem__(self, idx):
        return self.data[idx[0]][idx[1]]

In [13]:
A=Array([[35,63,13],[10,8,7]])
A[0,2]


Out[13]:
13

In [524]:
class Array:
    "Una clase minima para algebra lineal"    
    def __init__(self, list_of_rows): 
        "Constructor y validador"
        # obtener dimensiones
        self.data = list_of_rows
        nrow = len(list_of_rows)
        #  ___caso vector: redimensionar correctamente
        if not isinstance(list_of_rows[0], list):
            nrow = 1
            self.data = [[x] for x in list_of_rows]
        # ahora las columnas deben estar bien aunque sea un vector
        ncol = len(self.data[0])
        self.shape = (nrow, ncol)
        # validar tamano correcto de filas
        if any([len(r) != ncol for r in self.data]):
            raise Exception("Las filas deben ser del mismo tamano")
    
    def __setitem__(self, idx, value):
        self.data[idx[0]][idx[1]] = value
        
    def __repr__(self):
        return "\n".join(str(x) for x in self.data)
    
    def __str__(self):
        return "\n".join(repr(x) for x in self.data)

In [525]:
A=Array([[35,63,13],[10,8,7]])
A[0,2]=8

In [526]:
A.data


Out[526]:
[[35, 63, 8], [10, 8, 7]]

In [527]:
print(A)


[35, 63, 8]
[10, 8, 7]

Ejercicio 3.1

Hacer la matriz identidad


In [77]:
##ejercicio 3.1
def zeros (x, y): 
    zeros = [[0 for x in range(x)] for y in range(y)]
    return zeros

In [78]:
Ma=zeros(5,5)

In [79]:
print(Ma)


[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]

In [80]:
zeros(5,5)


Out[80]:
[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]]

Otra manera de hacer una matriz de ceros

Sólo que esta sólo puede ser cuadrada


In [87]:
def ceros(n):
    ceros = [[0]*n for i in range(n)]
    return ceros

In [88]:
ceros(5)


Out[88]:
[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]]

Ejercicio 3.2

Hacer la matriz identidad


In [75]:
#Ejercicio 3.2
def eye(n):
    matrix = [[0]*n for i in range(n)]
    for i in range(n):
        matrix[i][i] = 1
    return matrix

In [76]:
eye(5)


Out[76]:
[[1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [0, 0, 0, 1, 0],
 [0, 0, 0, 0, 1]]

Ejercicio 4

Hacer una matriz transpuesta


In [178]:
def transpuesta(list_of_rows):
        rows, cols = len(list_of_rows), len(list_of_rows[0])
        transpuesta=[[list_of_rows[i][j] for i in range(rows)] for j in range(cols)]
        return transpuesta

In [179]:
A.data


Out[179]:
[[35, 63, 13], [10, 8, 7]]

In [180]:
transpuesta(A.data)


Out[180]:
[[35, 10], [63, 8], [13, 7]]

Ejercicio 5

Suma de Matrices


In [185]:
class Array:
    "Una clase minima para algebra lineal"    
    def __init__(self, list_of_rows): 
        "Constructor y validador"
        # obtener dimensiones
        self.data = list_of_rows
        nrow = len(list_of_rows)
        #  ___caso vector: redimensionar correctamente
        if not isinstance(list_of_rows[0], list):
            nrow = 1
            self.data = [[x] for x in list_of_rows]
        # ahora las columnas deben estar bien aunque sea un vector
        ncol = len(self.data[0])
        self.shape = (nrow, ncol)
        # validar tamano correcto de filas
        if any([len(r) != ncol for r in self.data]):
            raise Exception("Las filas deben ser del mismo tamano")
        
    def __add__(self, other):
        "Hora de sumar"
        if isinstance(other, Array):
            if self.shape != other.shape:
                raise Exception("Las dimensiones son distintas!")
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = self.data[r][c] + other.data[r][c]
            return newArray
        elif isinstance(2, (int, float, complex)): # en caso de que el lado derecho sea solo un numero
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = self.data[r][c] + other
            return newArray
        elif isinstance(2, (int, float, complex)): # en caso de que el lado izquierdo sea solo un numero
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = other + self.data[r][c] 
            return newArray
        else:
            return NotImplemented # es un tipo de error particular usado en estos metodos

In [186]:
A = Array([[1,2], [3,4]])
C = A + 1
C.data


Out[186]:
[[2, 3], [4, 5]]

In [187]:
D = A + 1
D.data


Out[187]:
[[2, 3], [4, 5]]

In [330]:
class Array:
    "Una clase minima para algebra lineal"    
    def __init__(self, list_of_rows): 
        "Constructor y validador"
        # obtener dimensiones
        self.data = list_of_rows
        nrow = len(list_of_rows)
        #  ___caso vector: redimensionar correctamente
        if not isinstance(list_of_rows[0], list):
            nrow = 1
            self.data = [[x] for x in list_of_rows]
        # ahora las columnas deben estar bien aunque sea un vector
        ncol = len(self.data[0])
        self.shape = (nrow, ncol)
        # validar tamano correcto de filas
        if any([len(r) != ncol for r in self.data]):
            raise Exception("Las filas deben ser del mismo tamano")
        
    def __add__(self, other):
        "Hora de sumar"
        if isinstance(other, Array):
            if self.shape != other.shape:
                raise Exception("Las dimensiones son distintas!")
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = self.data[r][c] + other.data[r][c]
            return newArray
        elif isinstance(2, (int, float, complex)): # en caso de que el lado derecho sea solo un numero
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = self.data[r][c] + other
            return newArray
        else:
            return NotImplemented # es un tipo de error particular usado en estos metodos
        
    def __radd__(self, other):
        if isinstance(1, (int, float, complex)): # en caso de que el lado derecho sea solo un numero
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = other + self.data[r][c]
            return newArray
        else:
            return NotImplemented # es un tipo de error particular usado en estos metodos
             
        
    def __sub__(self, other):
        "Hora de restar"
        if isinstance(other, Array):
            if self.shape != other.shape:
                raise Exception("Las dimensiones son distintas!")
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = self.data[r][c] - other.data[r][c]
            return newArray
        elif isinstance(2, (int, float, complex)): # en caso de que el lado derecho sea solo un numero
            rows, cols = self.shape
            newArray = Array([[0. for c in range(cols)] for r in range(rows)])
            for r in range(rows):
                for c in range(cols):
                    newArray.data[r][c] = self.data[r][c] - other
            return newArray
        else:
            return NotImplemented # es un tipo de error particular usado en estos metodos

In [333]:
A = Array([[1,2], [3,4]])
C = -3+A
C.data


Out[333]:
[[-2, -1], [0, 1]]

Hacer una matriz con el mismo número en todas las entradas


In [318]:
def const(other, rows, cols):
    constant = Array ([[[other]*cols for c in range(rows)]])
    return constant

In [323]:
x = const (3,5,4)

In [334]:
x.data


Out[334]:
[[[3, 3, 3, 3], [3, 3, 3, 3], [3, 3, 3, 3], [3, 3, 3, 3], [3, 3, 3, 3]]]

Ejercicio 6

Multiplicación de Matrices


In [520]:
class Array:
    "Una clase minima para algebra lineal"    
    def __init__(self, list_of_rows): 
        "Constructor y validador"
        # obtener dimensiones
        self.data = list_of_rows
        nrow = len(list_of_rows)
        #  ___caso vector: redimensionar correctamente
        if not isinstance(list_of_rows[0], list):
            nrow = 1
            self.data = [[x] for x in list_of_rows]
        # ahora las columnas deben estar bien aunque sea un vector
        ncol = len(self.data[0])
        self.shape = (nrow, ncol)
        # validar tamano correcto de filas
        if any([len(r) != ncol for r in self.data]):
            raise Exception("Las filas deben ser del mismo tamano")
        
    def __mul__(self, other):
        "Hora de multiplicar"
        if isinstance(other, Array):
            if self.shape[1] != other.shape[0]:
                raise Exception("Las dimensiones de filas y columnas no coinciden!")
            rows1, cols1 = self.shape
            rows2, cols2 = other.shape
            Array_mult = Array([[0. for c in range (cols2)] for r in range(rows1)])
            for r in range(rows1):
                for c in range(cols2):
                    for k in range(rows2):
                        Array_mult.data[r][c] += self.data[r][k] * other.data[k][c]
            return Array_mult
        elif isinstance(2, (int, float, complex)): # Multiplica por un escalar
            rows1, cols1 = self.shape
            Array_mult = Array([[0. for c in range(cols1)] for r in range(rows1)])
            for r in range(rows1):
                for c in range(cols1):
                    for k in range(rows1):
                        Array_mult.data[r][c] = (self.data[r][c] * other)
            return Array_mult
        else:
            return NotImplemented # es un tipo de error particular usado en estos metodos

In [521]:
A = Array ([[1,2], [3,4]])
B = Array ([[1,2,3], [3,4,5]])
C = A * B
C.data


Out[521]:
[[7.0, 10.0, 13.0], [15.0, 22.0, 29.0]]

In [523]:
A = Array ([[1,2], [3,4]])
C = A * 5
C.data


Out[523]:
[[5, 10], [15, 20]]

Otra manera de hacer multiplicación de matrices


In [433]:
def matmult(m1,m2):
    r=[]
    m=[]
    for i in range(len(m1)):
        for j in range(len(m2[0])):
            sums=0
            for k in range(len(m2)):
                sums=sums+(m1[i][k]*m2[k][j])
            r.append(sums)
        m.append(r)
        r=[]
    return m

In [436]:
A = [[4,6], [7,8]]
B = [[1,2,3], [3,4,5]]
c=matmult(A,B)

In [437]:
c


Out[437]:
[[22, 32, 42], [31, 46, 61]]

In [485]:
def cmatmult(m1,m2):
    r=[]
    m=[]
    for i in range(len(m1)):
        for j in range(len(m1[0])):
            sums=0
            for k in range(len(m1)):
                sums=(m1[i][j]*m2)
            r.append(sums)
        m.append(r)
        r=[]
    return m

In [486]:
A = [[1,2], [3,4]]
c=cmatmult(A,3)

In [487]:
c


Out[487]:
[[3, 6], [9, 12]]

In [ ]: